; Sazerland-Kohen algoritm made on 8 may 2000 by ago
; last changed at 14 may

X1    equ 64
Y1    equ 64
X2    equ 191
Y2    equ 183

clipBelow:
 ld   a,h   ; y1
 sub  Y2
 ld   c,a   ; c=y1-Y2
 ld   a,h   ; y1
 sub  d
 ld   h,a   ; h=y1-y2
 ld   a,e
 sub  l     ; a=x2-x1
 push af
 jr   nc,@+4
 cpl        ; a=-a
 inc  a    
 ld   b,a   ; b=|x2-x1|
 xor  a
 rept 8
 rr   c
 jr   nc,@+3
 add  a,b
 rra
 endr
 rr   c     ; ac=b*c ; a - high, c - low

 rept 8
 rl   c
 rl   a
 sub  h
 jr   nc,@+3
 add  a,h
 endr

 ld   a,c
 rla
 cpl        ; a=ac/h
 ld   c,a
 pop  af
 ld   a,c
 jr   nc,@+4
 cpl
 inc  a
 add  a,l   ; x1+=(x2-x1)*(y1-Y2)/(y1-y2)
 ld   l,a   ;
 ld   h,Y2  ; y1=Y2=183

;                                                      ; system of cords:
Sazerland:              ; in hl - point1 (l=x1,h=y1)   ; 0   ...   254
                        ;    de = point2 (e=x2,d=y2)   ; ... 
                        ;    all registers E[0..254]   ; 254

 ld   bc,0              ; code1=code2=0
 ld   a,Y2              ; a=Y2=X2 - last right (down)column (line) in zone

 cp   h     ; y1>Y2 ?   ; if yes, set 3,c
 rl   c     ;           ;
 cp   d     ; y2>Y2 ?   ; if yes, set 3,b
 rl   b     ;           ;

 ld   a,X2
 cp   l     ; x1>X2 ?   ; if yes, set 2,c
 rl   c     ;           ;
 cp   e     ; x2>X2 ?   ; if yes, set 2,b
 rl   b     ;           ;

 ld   a,X1-1            ; a=Y1-1=X1-1 - first on left (up) edge not in zone!

 cp   h     ; y1<=Y1-1 ?; if yes, set 1,c
 ccf                    ;
 rl   c                
 cp   d     ; y2<=Y1-1 ?; if yes, set 1,b
 ccf                    ;
 rl   b     
 cp   l     ; x1<=X1-1 ?; if yes, set 0,c
 ccf                    ;
 rl   c     
 cp   e     ; x2<=X2-1 ?; if yes, set 0,b
 ccf                    ;
 rl   b   
 
 ld   a,b   ; if code1=code2, then both points in zone, we can draw
 or   c
 ret  z


 ld   a,b   ; if notZero, then both points outZone on same side 
 and  c     ; (on left|up|down|right) => line not moving into Screen
 ret  nz    ; then return, will nothing to draw

 ld   a,c   ; code1
 or   a
 jr   nz,noSwapSazerland
 ld   a,h   ;
 ld   h,d   ; swapping x1y1 with x2y2
 ld   d,a   ;
 ld   a,l   ;
 ld   l,e   ;
 ld   e,a   ;
 ld   a,b   ; code1 (work) := code2

noSwapSazerland:
 rr   a
 jp   nc,clipAbove
 ld   a,X1  ; 64
 sub  l
 ld   c,a   ; c=X1-x1
 ld   a,e   ; x2
 sub  l
 ld   l,a   ; l=x2-x1
 ld   a,d
 sub  h     ; a=y2-y1
 push af
 jr   nc,@+4
 cpl        ; a=-a
 inc  a     ;
 ld   b,a   ; b=|y2-y1|
 xor  a
 rept 8
 rr   c
 jr   nc,@+3
 add  a,b
 rra
 endr
 rr   c     ; ac=b*c ; a - high, c - low

 rept 8
 rl   c
 rl   a
 sub  l
 jr   nc,@+3
 add  a,l
 endr

 ld   a,c
 rla
 cpl        ; a=ac/l
 ld   c,a
 pop  af
 ld   a,c
 jr   nc,@+4
 cpl
 inc  a
 add  a,h   ; y1+=(y2-y1)*(X1-x1)/(x2-x1)
 ld   h,a   ;
 ld   l,X1  ; x1=X1=64
 jp   Sazerland

clipAbove:
 rr   a
 jp   nc,clipRight
 ld   a,Y1  ; 64
 sub  h
 ld   c,a   ; c=Y1-y1
 ld   a,d   ; y2
 sub  h
 ld   h,a   ; h=y2-y1
 ld   a,e
 sub  l     ; a=x2-x1
 push af
 jr   nc,@+4
 cpl        ; a=-a
 inc  a     ;
 ld   b,a   ; b=|x2-x1|
 xor  a
 rept 8
 rr   c
 jr   nc,@+3
 add  a,b
 rra
 endr
 rr   c     ; ac=b*c ; a - high, c - low

 rept 8
 rl   c
 rl   a
 sub  h
 jr   nc,@+3
 add  a,h
 endr

 ld   a,c
 rla
 cpl        ; a=ac/h
 ld   c,a
 pop  af
 ld   a,c
 jr   nc,@+4
 cpl
 inc  a
 add  a,l   ; x1+=(x2-x1)*(Y1-y1)/(y2-y1)
 ld   l,a   ;
 ld   h,Y1  ; y1=Y1
 jp   Sazerland

clipRight:
 rr   a
 jp   nc,clipBelow
 ld   a,l   ; x1
 sub  X2
 ld   c,a   ; c=x1-X2
 ld   a,l   ; x1
 sub  e
 ld   l,a   ; l=x1-x2
 ld   a,d
 sub  h     ; a=y2-y1
 push af
 jr   nc,@+4
 cpl        ; a=-a
 inc  a     ;
 ld   b,a   ; b=|y2-y1|
 xor  a
 rept 8
 rr   c
 jr   nc,@+3
 add  a,b
 rra
 endr
 rr   c     ; ac=b*c ; a - high, c - low

 rept 8
 rl   c
 rl   a
 sub  l
 jr   nc,@+3
 add  a,l
 endr

 ld   a,c
 rla
 cpl        ; a=ac/l
 ld   c,a
 pop  af
 ld   a,c
 jr   nc,@+4
 cpl
 inc  a
 add  a,h   ; y1+=(y2-y1)*(x1-X2)/(x1-x2)
 ld   h,a   ;
 ld   l,X2  ; x1=X2=191
 jp   Sazerland